﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Entity;
using TeamOPSchoolCup.Domain.POCO;
using TeamOPSchoolCup.Domain.POCO.Members;
using System.Data.Entity.ModelConfiguration.Conventions;
using TeamOPSchoolCup.Domain.POCO.Ranking;
using TeamOPSchoolCup.Domain.POCO.Meetings;

namespace TeamOPSchoolCup.Domain.DAL
{
  public class EFDbContext : DbContext
  {
    //Although we might want the specific types instead...
    public DbSet<Member> Members { get; set; }
    public DbSet<Region> Regions { get; set; }
    public DbSet<Team> Teams { get; set; }
    public DbSet<TeamMembership> TeamMemberships { get; set; }
    public DbSet<Result> Results { get; set; }
    public DbSet<Event> Events { get; set; }
    public DbSet<NSSF> NSSFs { get; set; }
    public DbSet<Sport> Sports { get; set; }
    

    //Users DataTables
    public DbSet<Coach> Coaches { get; set; }
    public DbSet<NSSFRep> NSSFReps { get; set; }
    public DbSet<SCC> SCCs { get; set; }
    public DbSet<Student> Students { get; set; }
    public DbSet<ISFAdmin> ISFAdmins { get; set; }

    //Ranking-stuff
    public DbSet<BestStudentResult> BestStudentResults { get; set; }
    public DbSet<Point> Points { get; set; }
    public DbSet<TeamResult> TeamResults { get; set; }
    public DbSet<BestTeamResult> BestTeamResults { get; set; }

    //Meeting
    public DbSet<Meeting> Meetings { get; set; }
    public DbSet<ISFMeeting> ISFMeetings { get; set; }
    public DbSet<RegionalMeeting> RegionalMeetings { get; set; }
    public DbSet<UnofficialMeeting> UnofficialMeetings { get; set; }
    
    //Constructor
    public EFDbContext() : base("TeamOPSchoolCup")
    {
      this.Configuration.LazyLoadingEnabled = true;
    }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
      base.OnModelCreating(modelBuilder);

      //1-1 relations
      //Member class with his subs
      modelBuilder.Entity<Member>().HasOptional(s => s.Student);
      modelBuilder.Entity<Student>().HasRequired(m => m.Member);
      modelBuilder.Entity<Member>().HasOptional(s => s.Coach);
      modelBuilder.Entity<Coach>().HasRequired(m => m.Member);
      modelBuilder.Entity<Member>().HasOptional(s => s.SCC);
      modelBuilder.Entity<SCC>().HasRequired(m => m.Member);
      modelBuilder.Entity<Member>().HasOptional(s => s.NSSFRep);
      modelBuilder.Entity<NSSFRep>().HasRequired(m => m.Member);
      modelBuilder.Entity<Member>().HasOptional(s => s.ISFAdmin);
      modelBuilder.Entity<ISFAdmin>().HasRequired(m => m.Member);

      modelBuilder.Entity<TeamMembership>().HasKey(tm => new { tm.StudentId,tm.TeamId });
      
      //Rankings
      modelBuilder.Entity<BestStudentResult>().HasKey(bsr => new { bsr.StudentId, bsr.EventId, bsr.CompetitionYear, bsr.IsOfficial });
      modelBuilder.Entity<TeamResult>().HasKey(tr => new { tr.MeetingId, tr.TeamId });
      modelBuilder.Entity<BestTeamResult>().HasKey(btr => new { btr.TeamId, btr.MeetingId, btr.CompetitionYear });

      //Region class
      modelBuilder.Entity<Region>().HasOptional(r => r.Parent);
      modelBuilder.Entity<Region>().HasOptional(r => r.NSSF);
      modelBuilder.Entity<NSSF>().HasRequired(n => n.Region);
     
      //Meetings
      modelBuilder.Entity<ISFMeeting>().HasKey(im => new { im.MeetingId });
      modelBuilder.Entity<ISFMeeting>().HasRequired(im => im.Meeting).WithOptional(m => m.ISFMeeting);
      modelBuilder.Entity<RegionalMeeting>().HasKey(im => new { im.MeetingId });
      modelBuilder.Entity<RegionalMeeting>().HasRequired(im => im.Meeting).WithOptional(m => m.RegionalMeeting);
      modelBuilder.Entity<UnofficialMeeting>().HasKey(im => new { im.MeetingId });
      modelBuilder.Entity<UnofficialMeeting>().HasRequired(im => im.Meeting).WithOptional(m => m.UnofficialMeeting);

      //Conventions
      modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
      modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();
      
    }
  }
}
